home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-17 | 27.1 KB | 1,416 lines |
- ;QMouse.s
- ;Written by Dan Babcock
-
- ;Note: This source was assembled with Macro68. If you don't have Macro68
- ;(shame) it may be easily modified for use under A68K.
-
- exeobj
- objfile 'c:QMouse'
-
- IFND _LVOSystemTagList
- _LVOSystemTagList equ -$25E
- ENDC
-
- SCREENLISTSIZE equ 32 ;maximum number of screens to keep track of
- POINTERLISTSIZE equ 32
- HANDLERPRI equ 60 ;priority of input.device handler
- MaxCopperSize equ 500
-
- SysBackground equ $e ;Offset into gb_copinit copper list -- 2.04 only!
- DefColor equ $fff ;white
-
- move.l 4,a6
- cmp.w #37,LIB_VERSION(a6)
- bhs.s .GoodVer
- lea Sorry(pc),a0
- bsr.s Print
- moveq #100,d0
- rts
-
- .GoodVer:
- ;Allocate global data structure
- move.l #Data_Sizeof,d0
- move.l #MEMF_CLEAR,d1
- SYS AllocMem
- tst.l d0
- bne AllocOK
- rts
-
- Print:
- ;Output a string to the CLI
- ;Enter with pointer to a zero-terminated string in a0
- ;All registers are preserved
-
- movem.l d0-d7/a0-a6,-(sp)
- move.l a0,a5
- lea DosName(pc),a1
- move.l 4,a6
- SYS OldOpenLibrary
- tst.l d0
- beq.s .End
- move.l d0,a6
- move.l a5,a0
- move.l a5,a4
- .PrintLine:
- tst.b (a5)+
- bne .PrintLine
- subq.l #1,a5
- sub.l a0,a5
- SYS Output
- move.l d0,d1
- move.l a4,d2
- move.l a5,d3
- SYS Write
- move.l a6,a1
- move.l 4,a6
- SYS CloseLibrary
- .End: movem.l (sp)+,d0-d7/a0-a6
- rts
-
- dc.b '$VER: QMouse V2.02 (22.2.92)',$a,0
- Sorry: dc.b 'Sorry, this program requires Kickstart 2.0!',$a,0
- even
-
- AllocOK:
- move.l d0,a5
- lea GlobalPtr(pc),a0
- move.l a5,(a0)
-
- ;Allocate chip RAM data.
- move.l #CData_Sizeof,d0
- move.l #MEMF_CLEAR+MEMF_CHIP,d1
- SYS AllocMem
- move.l d0,ChipData(a5)
- beq CleanUp
-
- ;Initialize static data
- move.b #HANDLERPRI,InputInterrupt+LN_PRI(a5)
- move.l a5,InputInterrupt+IS_DATA(a5)
- moveq #1,d0
- move.l d0,ClickCount(a1)
-
- ;Open dos.library
- lea DosName(pc),a1
- SYS OldOpenLibrary
- move.l d0,DosBase(a5)
- beq CleanUp
-
- ;Parse command line
- lea Template(pc),a0
- move.l a0,d1
- lea Options(a5),a0
- move.l a0,d2
- moveq #0,d3 ;no custom rdarg structure
- move.l DosBase(a5),a6
- SYS ReadArgs
- move.l d0,ArgPtr(a5)
- beq CleanUp
- move.l 4,a6
-
- ;Process QUIT option, if selected.
- tst.l QuitOption(a5)
- beq.s .SkipQuit
- lea ProcName(pc),a1
- SYS FindTask
- tst.l d0
- beq CleanUp
- move.l d0,a1
- move.l TC_Userdata(a1),d0
- SYS Signal ;tell task to quit
- bsr CleanUp
- bra .Exit
- .SkipQuit:
-
- ;If already installed, kill the existing process.
- lea ProcName(pc),a1
- SYS FindTask
- tst.l d0
- beq.s .NotInstalled
- move.l d0,a1
- move.l TC_Userdata(a1),d0
- SYS Signal ;tell task to quit
-
- moveq #26,d2
- .Kill: subq.l #1,d2
- beq .Exit
- move.l DosBase(a5),a6
- moveq #2,d1
- SYS Delay
- lea ProcName(pc),a1
- move.l 4,a6
- SYS FindTask
- tst.l d0
- bne .Kill
- .NotInstalled:
-
- ;Open intuition.library
- lea IntName(pc),a1
- SYS OldOpenLibrary
- move.l d0,IntBase(a5)
- beq CleanUp
-
- ;Open graphics.library
- lea GraphName(pc),a1
- SYS OldOpenLibrary
- move.l d0,GraphBase(a5)
- beq CleanUp
-
- ;Open layers.library
- lea LayersName(pc),a1
- SYS OldOpenLibrary
- move.l d0,LayersBase(a5)
- beq CleanUp
-
- ;Get stack for command.
- move.l DosBase(a5),a6
- SYS Cli
- move.l d0,a0
- move.l cli_DefaultStack(a0),d0
- lsl.l #2,d0
- lea CmdStackSize(pc),a0
- move.l d0,(a0)
- move.l 4,a6
-
- ;Copy resident part of code into allocated memory
- lea StartAllocCode(pc),a0 ;source
- lea ResidentCode(a5),a1 ;destination
- move.l #ResidentCodeSize,d0 ;size
- SYS CopyMem
- SYS CacheClearU ;for 020/030/040
-
- ;Start a process
- move.l DosBase(a5),a6
- lea ResidentCode(a5),a0
- lea EntryPoint(pc),a1
- move.l a0,(a1)
- lea ProcName-StartAllocCode+ResidentCode(a5),a0
- lea ProcNamePtr(pc),a1
- move.l a0,(a1)
- lea NewProcTags(pc),a0
- move.l a0,d1
- SYS CreateNewProc
-
- ;Exit back to CLI
- .Exit: moveq #0,d0
- rts
-
- ***************************************************************************
- * The following code is copied into allocated memory. *
- ***************************************************************************
-
- StartAllocCode:
- move.l 4,a6
- move.l GlobalPtr(pc),a5
- lea IntRoutine(pc),a0
- move.l a0,InputInterrupt+IS_CODE(a5)
-
- ;Initialize damping constant.
- move.l AccelOption(a5),d0
- beq.s .NoDamp
- move.l d0,a0
- move.l (a0),d0
- subq.l #1,d0
- move.l ThreshOption(a5),d1
- beq.s .DefThresh
- move.l d1,a0
- move.l (a0),d1
- .DefThresh:
- addq.l #1,d1
- mulu.w d0,d1
- move.w d1,DampingConstant(a5)
- .NoDamp:
-
- ;Allocate signals
- moveq #NumSigs-1,d2
- lea Sigs(a5),a2
- .SigLoop: moveq #-1,d0
- SYS AllocSignal
- tst.l d0
- bmi CleanUp
- moveq #0,d1
- bset d0,d1
- move.l d1,(a2)+
- dbra d2,.SigLoop
-
- ;Initialize semaphore(s)
- lea MySemaphore(a5),a0
- SYS InitSemaphore
-
- move.l ThisTask(a6),a0
- move.l a0,Task(a5)
- move.l QuitSig(a5),TC_Userdata(a0)
-
- ;Install no-flicker option if selected.
- tst.l FlickerOption(a5)
- beq.s .NoFlicker
- move.l GraphBase(a5),a0
- move.l gb_CopInit(a0),a0
- move.l a0,OriginalCopInit(a5)
- move.l ChipData(a5),a1
- lea Copper(a1),a1
- move.l a1,a2
- move.w #MaxCopperSize/4-1,d0
- .CLoop: move.l (a0)+,d1
- cmp.l #$008A0000,d1
- beq.s .CopEnd
- move.l d1,(a1)+
- dbra d0,.CLoop
- clr.l FlickerOption(a5)
- bra.s .NoFlicker
- .CopEnd: move.l #$01800000,(a1)+
- move.l #$1607FFFE,(a1)+
- move.w #$0180,(a1)+
- move.l #$008A0000,2(a1)
- move.l a1,RealBackground(a5)
- move.l a2,cop1lc+_custom
- move.l GraphBase(a5),a0
- move.l a2,gb_CopInit(a0)
- cmp.w #color,SysBackground-2(a2)
- bne.s .DefColor
- move.w SysBackground(a2),(a1)
- bra.s .NoFlicker
- .DefColor:
- move.w #DefColor,(a1)
- .NoFlicker:
-
- ;Patch MANY system routines.
- lea PatchTable(pc),a2
- move.l a2,a3
- .Patch: move.w (a2)+,d0 ;get base
- beq.s .EndPatch
- move.l (a5,d0.w),a1 ;library base to patch
- move.w (a2)+,d0 ;get offset to new routine
- lea (a3,d0.w),a0
- move.l a0,d0 ;new routine address
- move.w (a2)+,a0 ;_LVO offset
- SYS SetFunction
- move.w (a2)+,d1
- move.l d0,(a5,d1.w)
- bra .Patch
- .EndPatch:
-
- ;Create an IORequest structure
- SYS CreateMsgPort
- move.l d0,InputMsgPort(a5)
- beq CleanUp
- move.l d0,a0
- moveq #IOSTD_SIZE,d0
- SYS CreateIORequest
- move.l d0,InputIORequest(a5)
- beq CleanUp
-
- ;Open the input.device
- lea InputName(pc),a0 ;device name
- moveq #0,d0 ;unit number
- move.l InputIORequest(a5),a1 ;IO request
- moveq #0,d1 ;flags
- SYS OpenDevice
- tst.l d0
- bne CleanUp
-
- ;Install input handler
- move.l InputIORequest(a5),a1
- move.w #IND_ADDHANDLER,IO_COMMAND(a1)
- lea InputInterrupt(a5),a0
- move.l a0,IO_DATA(a1)
- SYS DoIO
- tst.l d0
- bne CleanUp
- st HandlerInstalled(a5)
-
- ;Wait for signal(s)
- Wait:
- lea Sigs(a5),a0
- move.l (a0)+,d0
- moveq #NumSigs-2,d1
- .. add.l (a0)+,d0
- dbra d1,..
- move.l 4,a6
- SYS Wait
- move.l d0,d1
- and.l QuitSig(a5),d1
- bne.s SafeCleanUp
- move.l d0,d1
- and.l CLISig(a5),d1
- bne.s .Execute
- move.l d0,d1
- and.l WBenchToFrontSig(a5),d1
- bne.s .WBenchToFront
-
- ;Perform ScreenToBack
- move.l IntBase(a5),a6
- move.l ScreenPtr(a5),d0
- beq Wait
- clr.l ScreenPtr(a5)
- move.l d0,a0
- SYS ScreenToBack
- bra Wait
- .WBenchToFront:
- move.l IntBase(a5),a6
- SYS WBenchToFront
- bra Wait
- .Execute:
- ;Execute the desired command
- move.l DosBase(a5),a6
-
- move.l CmdOption(a5),d1
- beq Wait
- lea .Tags(pc),a0
- move.l a0,d2 ;tags
- SYS SystemTagList
- bra Wait
- .Tags: dc.l SYS_USERSHELL,0
- dc.l NP_StackSize
- CmdStackSize:
- dc.l 0
- dc.l 0 ;end of tag list
-
- SafeCleanUp:
- ;Make sure the SetFunction'ed vectors are still intact.
- lea PatchTable(pc),a0
- move.l a0,a2
- .Safe: move.w (a0)+,d0
- beq.s CleanUp
- move.l (a5,d0.w),a1 ;library base
- move.w (a0)+,d0
- lea (a2,d0.w),a3 ;address of new routine
- move.w (a0)+,d0
- cmp.l 2(a1,d0.w),a3
- bne Wait
- addq.l #2,a0
- bra .Safe
-
- CleanUp:
-
- ;Enter with global ptr in A5
-
- move.l 4,a6
-
- ;Remove input handler, if installed.
- tst.b HandlerInstalled(a5)
- beq.s .SkipHand
- move.l InputIORequest(a5),a1
- move.w #IND_REMHANDLER,IO_COMMAND(a1)
- lea InputInterrupt(a5),a0
- move.l a0,IO_DATA(a1)
- SYS DoIO
- .SkipHand:
-
- bsr RestoreMouse
- bsr RestoreScreen
-
- ;Restore original vectors.
- tst.l IntBase(a5)
- beq.s .SkipRestore
- tst.l OldCloseScreen(a5)
- beq.s .SkipRestore
-
- lea PatchTable(pc),a2
- .RestoreVecs:
- move.w (a2),d0
- beq.s .SkipRestore
- addq.l #4,a2 ;skip new routine info
- move.l (a5,d0.w),a1 ;get library base
- move.w (a2)+,a0 ;get _LVO
- move.w (a2)+,d0
- move.l (a5,d0.w),d0 ;old routine
- SYS SetFunction
- bra .RestoreVecs
- .SkipRestore:
-
- ;Delay for 1/10 second to ensure that no-one is using the patch code.
- move.l DosBase(a5),d0
- beq.s .SkipDelay
- move.l d0,a6
- moveq #5,d1
- SYS Delay
- .SkipDelay:
-
- ;Free argument structure
- tst.l DosBase(a5)
- beq.s .SkipFreeArg
- move.l DosBase(a5),a6
- move.l ArgPtr(a5),d1
- beq.s .SkipFreeArg
- SYS FreeArgs
- .SkipFreeArg:
-
- move.l 4,a6
-
- ;Free signals
- lea Sigs(a5),a2
- moveq #NumSigs-1,d2
- .SigLoop: move.l (a2)+,d1
- beq.s .NextSig
- moveq #-1,d0
- .BitLoop: addq.l #1,d0
- btst d0,d1
- beq .BitLoop
- SYS FreeSignal
- .NextSig: dbra d2,.SigLoop
-
- ;Remove flicker option, if selected.
- tst.l FlickerOption(a5)
- beq.s .SkipFlicker
- move.l OriginalCopInit(a5),a0
- move.l GraphBase(a5),a2
- move.l gb_CopInit(a2),a1
- .CLoop: move.l (a1)+,(a0)+
- cmp.l #$008A0000,(a0)
- bne .CLoop
- move.l OriginalCopInit(a5),gb_CopInit(a2)
- move.l OriginalCopInit(a5),cop1lc+_custom
- .SkipFlicker:
-
- ;Close intuition.library
- move.l IntBase(a5),d0
- beq.s .SkipCloseInt
- move.l d0,a1
- SYS CloseLibrary
- .SkipCloseInt:
-
- ;Close graphics.library
- move.l GraphBase(a5),d0
- beq.s .SkipCloseGraph
- move.l d0,a1
- SYS CloseLibrary
- .SkipCloseGraph:
-
- ;Close dos.library
- move.l DosBase(a5),d0
- beq.s .SkipCloseDos
- move.l d0,a1
- SYS CloseLibrary
- .SkipCloseDos:
-
- ;Close layers.library
- move.l LayersBase(a5),d0
- beq.s .SkipCloseLayers
- move.l d0,a1
- SYS CloseLibrary
- .SkipCloseLayers:
-
- ;Close input.device
- move.l InputIORequest(a5),d0
- beq.s .SkipCloseDev
- move.l d0,a1
- tst.b IO_ERROR(a1) ;was there an error?
- bne.s .SkipCloseDev ;yes, don't close
- SYS CloseDevice
- .SkipCloseDev:
-
- ;Delete IORequest structure
- move.l InputMsgPort(a5),a0
- SYS DeleteMsgPort
- move.l InputIORequest(a5),a0
- SYS DeleteIORequest
-
- ;Free chip data.
- tst.l ChipData(a5)
- beq.s .SkipChipData
- move.l ChipData(a5),a1
- move.l #CData_Sizeof,d0
- SYS FreeMem
- .SkipChipData:
-
- ;Deallocate global structure. Note that this code is (sometimes) executed
- ;within the memory that we are freeing, so we are careful to terminate with
- ;a JMP.
- move.l a5,a1
- move.l #Data_Sizeof,d0
- jmp _LVOFreeMem(a6)
-
- ;Semaphore routines
-
- GetSemaphore:
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea MySemaphore(a0),a0
- move.l 4,a6
- SYS ObtainSemaphore
- movem.l (sp)+,a0/a6
- rts
- FreeSemaphore:
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea MySemaphore(a0),a0
- move.l 4,a6
- SYS ReleaseSemaphore
- movem.l (sp)+,a0/a6
- rts
-
- ;****************** SetFunction'ed routines ***************
-
- patch macro
- dc.w \1
- dc.w New\2-PatchTable
- dc.w _LVO\2
- dc.w Old\2
- endm
-
- PatchTable:
- patch IntBase,CloseScreen
- patch IntBase,CloseWindow
- patch IntBase,OpenScreen
- patch IntBase,ScreenToFront
- patch IntBase,ScreenToBack
- patch IntBase,OpenScreenTagList
- patch IntBase,WBenchToFront
- patch IntBase,WBenchToBack
- patch IntBase,SetPointer
- patch IntBase,ClearPointer
- patch IntBase,DisplayBeep
- patch GraphBase,LoadView
- dc.w 0
-
- NewDisplayBeep:
- move.l GlobalPtr(pc),a1
- tst.l BeepOption(a1)
- beq.s .NormalBeep
- rts
- .NormalBeep:
- move.l OldDisplayBeep(a1),-(sp)
- rts
-
- NewSetPointer:
- bsr GetSemaphore
- movem.l d4-d5/a2-a3/a5,-(sp)
- move.l GlobalPtr(pc),a5
- lea PointerList(a5),a2
-
- ;Find if window is already in table and find empty spot.
- moveq #POINTERLISTSIZE-1,d4
- sub.l a3,a3
- .WinSearch:
- move.l pt_Window(a2),d5
- bne.s .SkipSave
- move.l a2,a3
- .SkipSave:
- cmp.l d5,a0
- beq.s .Found
- lea pt_Sizeof(a2),a2
- dbra d4,.WinSearch
- move.l a3,a2
- move.l a2,d4
- beq.s .End ;no room in table, so forget it
- .Found: movem.l d0-d3/a0-a1,(a2)
- .End: cmp.l MBlankWindow(a5),a0
- beq.s .End1
- .SkipMBlank:
- movem.l (sp)+,d4-d5/a2-a3/a5
- subq.l #8,sp
- move.l a0,(sp)
- move.l GlobalPtr(pc),a0
- move.l OldSetPointer(a0),4(sp)
- move.l (sp)+,a0
- bsr FreeSemaphore
- rts
- .End1: movem.l (sp)+,d4-d5/a2-a3/a5
- bsr FreeSemaphore
- rts
-
- NewClearPointer:
- bsr GetSemaphore
- move.l GlobalPtr(pc),a1
- lea PointerList(a1),a1
- moveq #POINTERLISTSIZE-1,d0
- .ClearLoop:
- cmp.l pt_Window(a1),a0
- beq.s .Found
- lea pt_Sizeof(a1),a1
- dbra d0,.ClearLoop
- bra.s .End
- .Found: clr.l pt_Window(a1)
- .End: move.l GlobalPtr(pc),a1
- cmp.l MBlankWindow(a1),a0
- beq.s .End1
- .SkipMBlank:
- move.l OldClearPointer(a1),-(sp)
- .End1: bsr FreeSemaphore
- rts
-
- NewLoadView:
- pea .NewLoad(pc)
- move.l GlobalPtr(pc),a0
- move.l OldLoadView(a0),-(sp)
- rts
- .NewLoad:
- move.l GlobalPtr(pc),a0
- tst.l FlickerOption(a0)
- beq.s .End
- move.l RealBackground(a0),a1
- move.l GraphBase(a0),a0
- move.l gb_copinit(a0),a0
- move.w SysBackground(a0),(a1)
- .End: rts
-
- NewCloseScreen:
- bsr GetSemaphore
- move.l GlobalPtr(pc),a1
- lea ScreenList(a1),a1
- moveq #SCREENLISTSIZE-1,d0
- .Loop: cmp.l (a1),a0
- beq.s .Match
- addq.l #8,a1
- dbra d0,.Loop
- .End: move.l GlobalPtr(pc),a1
- pea RestoreWindow(pc)
- move.l OldCloseScreen(a1),-(sp)
- bsr FreeSemaphore
- rts
- .Match: clr.l (a1)
- bra .End
-
- NewCloseWindow:
- bsr GetSemaphore
- push a0
- SYS ClearPointer
- pop a0
- move.l GlobalPtr(pc),a1
- cmp.l MBlankWindow(a1),a0
- bne.s .SkipClear
- clr.l MBlankWindow(a1)
- .SkipClear:
- lea ScreenList+4(a1),a1
- moveq #SCREENLISTSIZE-1,d0
- .Loop: cmp.l (a1),a0
- beq.s .Match
- addq.l #8,a1
- dbra d0,.Loop
- .End: move.l GlobalPtr(pc),a1
- move.l OldCloseWindow(a1),-(sp)
- bsr FreeSemaphore
- rts
- .Match: clr.l -4(a1)
- bra .End
-
- MyRemember:
- bsr GetSemaphore
- bsr.s RememberWindow
- move.l a0,-(sp)
- move.l GlobalPtr(pc),a0
- move.l (a0,d0.w),d0
- move.l (sp)+,a0
- move.l d0,-(sp)
- bsr FreeSemaphore
- rts
-
- NewOpenScreen:
- move.w #OldOpenScreen,d0
- bra MyRemember
- NewOpenScreenTagList:
- move.w #OldOpenScreenTagList,d0
- bra MyRemember
- NewWBenchToFront:
- move.w #OldWBenchToFront,d0
- bsr MyRemember
- bra.s RestoreWindow
- NewWBenchToBack:
- move.w #OldWBenchToBack,d0
- bsr MyRemember
- bra.s RestoreWindow
- NewScreenToFront:
- move.w #OldScreenToFront,d0
- bsr MyRemember
- bra.s RestoreWindow
- NewScreenToBack:
- move.w #OldScreenToBack,d0
- bsr MyRemember
- bra.s RestoreWindow
-
- ;****************** End of SetFunction'ed routines ***************
-
- RememberWindow:
-
- ;This routine remembers the currently activated window on the current
- ;screen.
-
- movem.l d0-d1/a0-a2/a4-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l IntBase(a5),a4
- move.l 4,a6
- SYS Forbid
- move.l ib_ActiveScreen(a4),a0
- move.l ib_ActiveWindow(a4),a2
- SYS Permit
-
- ;Sanity checks
- move.l a0,d0
- beq.s .End
- move.l a2,d0
- beq.s .End
-
- lea ScreenList(a5),a1
- moveq #SCREENLISTSIZE-1,d0
- .ScLoop: cmp.l (a1),a0
- beq.s .Match
- addq.l #8,a1
- dbra d0,.ScLoop
-
- ;Screen not found. Add to screen list.
- lea ScreenList(a5),a1
- moveq #SCREENLISTSIZE-1,d0
- .AddLoop: tst.l (a1)
- beq.s .Match
- addq.l #8,a1
- dbra d0,.AddLoop
- bra.s .End ;table is full
- .Match:
- move.l a0,(a1)+ ;screen
- move.l a2,(a1) ;currently activated window
- .End: movem.l (sp)+,d0-d1/a0-a2/a4-a6
- rts
-
- RestoreWindow:
-
- ;This routine restores (re-activates) the previously activated window for
- ;this screen.
-
- bsr GetSemaphore
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea ScreenList(a0),a1
- move.l IntBase(a0),a6
- move.l ib_FirstScreen(a6),a0
- move.l a0,d0
- beq.s .End ;sanity check
- moveq #SCREENLISTSIZE-1,d0
- .Loop: cmp.l (a1),a0
- beq.s .Match
- addq.l #8,a1
- dbra d0,.Loop
- move.l sc_FirstWindow(a0),a0 ;default window
- move.l a0,d0
- beq.s .End ;sanity check
- bra.s .SkipMatch
- .Match:
- move.l 4(a1),a0
- .SkipMatch:
- SYS ActivateWindow
- .End: movem.l (sp)+,d0-d1/a0-a1/a6
- bsr FreeSemaphore
- rts
-
- ;***************************************************************************
- ;Start of input handler code
- ;***************************************************************************
-
- ;Get window associated with current mouse position.
- ;Returns Window in D0 and screen in D1.
-
- GetWindow:
- movem.l d2-d4/a0-a1/a4-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l LayersBase(a5),a6
- move.l IntBase(a5),a4
- move.l ib_FirstScreen(a4),d4
- .ScLoop: tst.l d4
- beq.s .ErrEnd
- move.l d4,a0
- move.l sc_NextScreen(a0),d4
- move.w ib_MouseX(a4),d0
- move.w ib_MouseY(a4),d1
- move.w sc_ViewPort+vp_Modes(a0),d2
- move.w d2,d3
- and.w #V_LACE,d2 ;interlace?
- bne.s .Lace ;yes
- lsr.w #1,d1
- .Lace: and.w #V_HIRES,d3 ;hires?
- bne.s .Hires ;yes
- lsr.w #1,d0
- .Hires: sub.w sc_ViewPort+vp_DxOffset(a0),d0
- bmi.s .ScLoop
- sub.w sc_ViewPort+vp_DyOffset(a0),d1
- bmi.s .ScLoop
- push a0
- lea sc_LayerInfo(a0),a0
- SYS WhichLayer
- pop d1
- tst.l d0
- beq.s .End
- move.l d0,a0
- move.l lr_Window(a0),d0
- .End: movem.l (sp)+,d2-d4/a0-a1/a4-a6
- rts
- .ErrEnd: moveq #0,d0
- moveq #0,d1
- bra .End
-
- DoWindowToFront:
-
- ;Perform a WindowToFront on the window in D0.
- ;Enter with global ptr in A1.
-
- tst.l d0
- beq.s .End1
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l IntBase(a1),a6
- move.l d0,a0
- move.l wd_WLayer(a0),a1
- move.l a1,d0
- beq.s .End
- move.l lr_ClipRect(a1),a1
- move.l a1,d0
- beq.s .End
- tst.l (a1)
- beq.s .End
- move.l wd_Flags(a0),d0
- and.l #WFLG_BACKDROP,d0
- bne.s .End
- SYS WindowToFront
- .End: movem.l (sp)+,d0-d1/a0-a1/a6
- .End1: rts
-
- BlankMouse:
- movem.l d0-d3/a0-a1/a5-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l IntBase(a5),a6
- move.l ib_ActiveWindow(a6),d0
- beq.s .End
- cmp.l MBlankWindow(a5),d0
- beq.s .End
- move.l d0,MBlankWindow(a5)
- move.l d0,a0
- move.l ChipData(a5),a1
- ; lea ZeroMouse(a1),a1 ;not needed
- moveq #1,d0 ;height
- moveq #16,d1 ;width
- moveq #0,d2 ;xoffset
- moveq #0,d3 ;yoffset
- pea .End(pc)
- move.l OldSetPointer(a5),-(sp)
- rts
- .End: movem.l (sp)+,d0-d3/a0-a1/a5-a6
- rts
-
- RestoreMouse:
- movem.l d0-d1/a0-a2/a5-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l IntBase(a5),a6
- tst.l MBlankWindow(a5)
- beq.s .End
-
- ;Look for window in pointer table. If present, do a SetPointer to restore
- ;the custom pointer. Otherwise call ClearPointer.
-
- move.l MBlankWindow(a5),a0
- clr.l MBlankWindow(a5)
- lea PointerList(a5),a1
- moveq #POINTERLISTSIZE-1,d0
- .WinLoop: cmp.l pt_Window(a1),a0
- beq.s .Found
- lea pt_Sizeof(a1),a1
- dbra d0,.WinLoop
- pea .End(pc)
- move.l OldClearPointer(a5),-(sp)
- rts
- .End: movem.l (sp)+,d0-d1/a0-a2/a5-a6
- rts
- .Found: move.l a1,a2
- movem.l (a2),d0-d3/a0-a1
- pea .End(pc)
- move.l OldSetPointer(a5),-(sp)
- rts
-
- RestoreScreen:
- push a5
- move.l GlobalPtr(pc),a5
- bclr #STB_SBlanked,Status(a5)
- beq.s .End
- move.w #DMAF_SETCLR+DMAF_COPPER+DMAF_RASTER,dmacon+_custom
- .End: pop a5
- rts
-
- SigTask:
- ;Enter with GlobalPtr in A1 and signal in D0.
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l Task(a1),a1
- move.l 4,a6
- SYS Signal
- movem.l (sp)+,d0-d1/a0-a1/a6
- rts
-
- IntRoutine:
- bsr GetSemaphore
- move.l a0,-(sp)
- tst.l FlickerOption(a1)
- beq.s .SkipFlick
- move.l GraphBase(a1),a0
- move.l gb_copinit(a0),a0
- cmp.w #color,Sysbackground-2(a0)
- bne.s .DefColor
- move.w SysBackground(a0),d0
- move.l RealBackground(a1),a0
- move.w d0,(a0)
- bra.s .SkipColor
- .DefColor:
- move.l RealBackground(a1),a0
- move.w #DefColor,(a0)
- .SkipColor:
- move.l (sp),a0
- .SkipFlick:
-
- ;Perform SunMouse
- tst.l SunMouseOption(a1)
- beq.s .SkipSunMouse1
- cmp.b #IECLASS_RAWMOUSE,ie_Class(a0)
- beq.s .SkipSunMouse1
- bclr #STB_SunMouse,Status(a1)
- beq.s .SkipSunMouse1
- bsr GetWindow
- movem.l a0-a1/a6,-(sp)
- move.l IntBase(a1),a6
- move.l d0,a0
- cmp.l ib_ActiveWindow(a6),a0
- beq.s .EndSun
- SYS ActivateWindow
- .EndSun: movem.l (sp)+,a0-a1/a6
- .SkipSunMouse1:
-
- move.l MBlankWindow(a1),d0
- beq.s .Loop
- push a6
- move.l IntBase(a1),a6
- cmp.l ib_ActiveWindow(a6),d0
- beq.s .EndMBW
- bsr RestoreMouse
- bsr BlankMouse
- .EndMBW: pop a6
-
- .Loop: cmp.b #IECLASS_TIMER,ie_Class(a0)
- beq .Next
-
- ;Reset screen blank
- tst.l SBlankOption(a1)
- beq.s .SkipSRestore
- move.l ie_TimeStamp(a0),ScreenTime(a1)
- bsr RestoreScreen
- .SkipSRestore:
-
- cmp.b #IECLASS_RAWKEY,ie_Class(a0)
- bne .NotKey
-
- ;Do Northgate keyboard mapping.
- tst.l NorthGateOption(a1)
- beq.s .SkipNorthgate
- push a2
- lea NorthgateTable(pc),a2
- move.w ie_Code(a0),d0
- bclr #7,d0
- .NorthgateLoop:
- move.b (a2),d1
- beq.s .EndNorthgate
- addq.l #3,a2
- cmp.b d0,d1
- bne.s .NorthgateLoop
- and.w #$80,ie_Code(a0)
- move.b -2(a2),d0
- or.b d0,ie_Code+1(a0)
- move.b -1(a2),d0
- bmi.s .EndNorthgate
- bset d0,ie_Qualifier+1(a0)
- .EndNorthgate:
- pop a2
- .SkipNorthgate:
-
- ;Blank mouse pointer
- tst.l MBlankOption(a1)
- beq.s .NoMBlank
- bsr BlankMouse
- .NoMBlank:
-
- btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
- beq .Next
- cmp.w #$37,ie_Code(a0) ;'m'?
- bne.s .NotM
-
- ;We found an Amiga-M. Defuse and perform action.
- clr.b ie_Class(a0)
- push a6
- move.l IntBase(a1),a6
- move.l ib_FirstScreen(a6),a0
- move.l a0,d0
- beq .EndM ;sanity check
- move.l a0,ScreenPtr(a1)
- move.l ScreenToBackSig(a1),d0
- bsr SigTask
- .EndM: pop a6
- bra .End
- .NotM:
- cmp.w #$36,ie_Code(a0) ;'n'?
- bne.s .NotN
-
- ;We found an Amiga-N. Defuse and perform action.
- clr.b ie_Class(a0)
- move.l WBenchToFrontSig(a1),d0
- bsr SigTask
- bra .End
- .NotN:
- tst.l CmdOption(a1)
- beq .Next
- cmp.w #$45,ie_Code(a0) ;ESC?
- bne .Next
- clr.b ie_Class(a0)
- move.l CLISig(a1),d0
- bsr SigTask
- bra .End
- .NotKey:
- cmp.b #IECLASS_RAWMOUSE,ie_Class(a0)
- bne .Next
- tst.l MBlankOption(a1)
- beq.s .NoRestore
- move.l ie_TimeStamp(a0),MouseTime(a1)
- bsr RestoreMouse
- .NoRestore:
-
- ;Perform SunMouse
- tst.l SunMouseOption(a1)
- beq.s .SkipSunMouse
- move.w ie_Qualifier(a0),d0
- and.w #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
- bne.s .SkipSunMouse
- cmp.w #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
- beq.s .SkipSunMouse
- bset #STB_SunMouse,Status(a1)
- .SkipSunMouse:
-
- ;Perform click-to-back.
- tst.l CTBOption(a1)
- beq.s .NoCTB
- cmp.w #IECODE_RBUTTON,ie_Code(a0)
- bne.s .NoCTB
- move.w ie_Qualifier(a0),d0
- btst #IEQUALIFIERB_LEFTBUTTON,d0
- beq.s .NoCTB
-
- movem.l d2/a0-a1/a6,-(sp)
- move.l IntBase(a1),a6
- bsr GetWindow
- tst.l d0
- beq.s .FlipScreen
- move.l d0,a1
- move.l wd_Flags(a1),d2
- and.l #WFLG_BACKDROP,d2
- bne.s .FlipScreen
-
- ;Is this the only window on this screen, except for backdrop windows?
- move.l wd_WScreen(a1),a1
- move.l sc_FirstWindow(a1),a1
- .BackLoop:
- cmp.l a1,d0
- beq.s .EBackLoop
- move.l wd_Flags(a1),d2
- and.l #WFLG_BACKDROP,d2
- beq.s .FlipWindow
- .EBackLoop:
- move.l (a1),a1
- move.l a1,d2
- bne .BackLoop
- .FlipScreen:
- tst.l d1
- beq.s .ECTB
- move.l GlobalPtr(pc),a1
- move.l d1,ScreenPtr(a1)
- move.l ScreenToBackSig(a1),d0
- bsr SigTask
- bra.s .ECTB
- .FlipWindow:
- move.l d0,a0
- SYS WindowToBack
-
- .ECTB: movem.l (sp)+,d2/a0-a1/a6
- clr.b ie_Class(a0)
- bra .Next
- .NoCTB:
-
- ;Perform click-to-front.
- tst.l CTFOption(a1)
- beq .NoCTF
- cmp.w #IECODE_LBUTTON,ie_Code(a0)
- bne .NoCTF
- bsr GetWindow
- tst.l d0
- beq .NoCTF
- push a2
- move.l CTFOption(a1),a2
- move.l (a2),d1
- pop a2
- cmp.l #1,d1
- bhi.s .MoreThanOne
- bsr DoWindowToFront
- bra.s .NoCTF
- .MoreThanOne:
- cmp.l ClickWindow(a1),d0
- beq.s .SameWindow
- move.l d0,ClickWindow(a1)
- moveq #1,d0
- move.l d0,ClickCount(a1)
- .Time: move.l ie_TimeStamp+TV_SECS(a0),ClickTime+TV_SECS(a1)
- move.l ie_TimeStamp+TV_MICRO(a0),ClickTime+TV_MICRO(a1)
- bra.s .NoCTF
- .SameWindow:
-
- ;Check to see whether MaxClickDelay has been exceeded. If not, increment
- ;ClickCount and compare with (CTFOption). If equal, do a WindowToFront.
- ;Window under pointer in D0.
-
- push d0
- movem.l d2-d3/a0-a1/a6,-(sp)
- move.l ClickTime+TV_SECS(a1),d0
- move.l ClickTime+TV_MICRO(a1),d1
- move.l ie_TimeStamp+TV_SECS(a0),d2
- move.l ie_TimeStamp+TV_MICRO(a0),d3
- move.l IntBase(a1),a6
- SYS DoubleClick
- movem.l (sp)+,d2-d3/a0-a1/a6
- tst.l d0
- beq.s .TimeExceeded
- addq.l #1,ClickCount(a1)
- push a0
- move.l CTFOption(a1),a0
- move.l (a0),d0
- pop a0
- cmp.l ClickCount(a1),d0
- bhi.s .NeedMoreClicks
- clr.l ClickCount(a1)
- pop d0
- bsr DoWindowToFront
- bra.s .NoCTF
- .TimeExceeded:
- moveq #1,d0
- move.l d0,ClickCount(a1)
- .NeedMoreClicks:
- pop d0
- bra .Time
- .NoCTF:
-
- ;Perform acceleration.
- tst.l AccelOption(a1)
- beq.s .Next
-
- push a2
- moveq #0,d0
- tst.l ThreshOption(a1)
- beq.s .T1
- move.l ThreshOption(a1),a2
- move.l (a2),d0
- .T1: move.w ie_X(a0),d1
- bpl.s .PosX
- neg.w d1
- .PosX: cmp.w d0,d1
- bls.s .SkipX ;below threshold
- move.l AccelOption(a1),a2
- move.l (a2),d1
- muls.w ie_X(a0),d1
- bpl.s .SubDampX
- add.w DampingConstant(a1),d1
- bra.s .DampX
- .SubDampX:
- sub.w DampingConstant(a1),d1
- .DampX: move.w d1,ie_X(a0)
- .SkipX: move.w ie_Y(a0),d1
- bpl.s .PosY
- neg.w d1
- .PosY: cmp.w d0,d1
- bls.s .EndAccel
- move.l AccelOption(a1),a2
- move.l (a2),d1
- muls.w ie_Y(a0),d1
- bpl.s .SubDampY
- add.w DampingConstant(a1),d1
- bra.s .DampY
- .SubDampY:
- sub.w DampingConstant(a1),d1
-
- .DampY: move.w d1,ie_Y(a0)
- .EndAccel:
- pop a2
-
- .Next: move.l a0,d1
- move.l (a0),d0
- move.l d0,a0
- bne .Loop
-
- ;Check for time-outs (mouse and screen blanking)
- move.l d1,a0
- tst.l MBlankOption(a1)
- beq.s .NoMTime
- move.l MBlankOption(a1),a0
- move.l (a0),d0 ;get value in seconds
- move.l d1,a0
- move.l ie_TimeStamp(a0),d1
- tst.l MouseTime(a1)
- beq.s .InitMBlank
- sub.l MouseTime(a1),d1
- cmp.l d0,d1 ;TimePassed ? UserSetting
- blo.s .NoMTime
- bsr BlankMouse
- .NoMTime:
- tst.l SBlankOption(a1)
- beq.s .End
- btst #STB_SBlanked,Status(a1)
- bne.s .End
- push a0
- move.l SBlankOption(a1),a0
- move.l (a0),d0 ;get value in seconds
- pop a0
- move.l ie_TimeStamp(a0),d1
- tst.l ScreenTime(a1)
- beq.s .InitSBlank
- sub.l ScreenTime(a1),d1
- cmp.l d0,d1 ;TimePassed ? UserSetting
- blo.s .End
- move.w #DMAF_COPPER+DMAF_RASTER,dmacon+_custom
- clr.w color+_custom
- bset #STB_SBlanked,Status(a1)
-
- .End: move.l (sp)+,d0
- bsr FreeSemaphore
- rts
- .InitMBlank:
- move.l ie_TimeStamp(a0),MouseTime(a1)
- bra .NoMTime
- .InitSBlank:
- move.l ie_TimeStamp(a0),ScreenTime(a1)
- bra .End
-
- GlobalPtr:
- dc.l 0
-
- NorthgateTable:
- dc.b $6b,$4f,IEQUALIFIERB_LSHIFT
- dc.b $6c,$4e,IEQUALIFIERB_LSHIFT
- dc.b $6d,$4c,IEQUALIFIERB_LSHIFT
- dc.b $6e,$4d,IEQUALIFIERB_LSHIFT
- dc.b 0
-
- ProcName: dc.b 'QMouse process',0
- InputName:
- dc.b 'input.device',0
- even
-
- EndAllocCode: ;end of code copied into allocated memory
- ;***********************************************************************
-
- NewProcTags:
- dc.l NP_Entry
- EntryPoint:
- dc.l 0
- dc.l NP_Name
- ProcNamePtr:
- dc.l 0
- dc.l NP_Cli,-1
- dc.l 0 ;end of tags
-
- Template: dc.b 'M=MBLANK/K/N,'
- dc.b 'S=SBLANK/K/N,'
- dc.b 'N=NOFLICKER/S,'
- dc.b 'CMD/K,'
- dc.b 'A=ACCELERATION/K/N,'
- dc.b 'T=THRESHOLD/K/N,'
- dc.b 'CTB=CLICKTOBACK/S,'
- dc.b 'CTF=CLICKTOFRONT/K/N,'
- dc.b 'SUNMOUSE/S,'
- dc.b 'NORTHGATE/S,'
- dc.b 'NOBEEP/S,'
- dc.b 'QUIT/S',0
-
- IntName: dc.b 'intuition.library',0
- GraphName:
- dc.b 'graphics.library',0
- DosName: dc.b 'dos.library',0
- LayersName:
- dc.b 'layers.library',0
-
- ;The ordering here is special: data registers first, then address
- ;registers, so that MOVEM may be used to save/restore the data.
-
- STRUCTURE pt,0
- LONG pt_Height
- LONG pt_Width
- LONG pt_XOffset
- LONG pt_YOffset
- LONG pt_Window
- LONG pt_Pointer
- LABEL pt_Sizeof
-
- ResidentCodeSize equ EndAllocCode-StartAllocCode
-
- STRUCTURE Data,0
- WORD Nothing ;to make zero special
- LONG Task
- LONG InputMsgPort
- LONG InputIORequest
- STRUCT InputInterrupt,IS_SIZE
- LONG IntBase
- LONG GraphBase
- LONG LayersBase
- STRUCT ScreenList,SCREENLISTSIZE*8
- STRUCT PointerList,POINTERLISTSIZE*pt_Sizeof
- LONG OldCloseScreen
- LONG OldCloseWindow
- LONG OldScreenToFront
- LONG OldScreenToBack
- LONG OldOpenScreen
- LONG OldOpenScreenTagList
- LONG OldWBenchToFront
- LONG OldWBenchToBack
- LONG OldLoadView
- LONG OldSetPointer
- LONG OldClearPointer
- LONG OldDisplayBeep
- LONG DosBase
- LONG ArgPtr
- STRUCT ResidentCode,ResidentCodeSize
- LONG MouseTime ;timeout for mouse blanking
- LONG ScreenTime ;for screen blanking
- LONG MBlankWindow
- WORD DampingConstant
- STRUCT MySemaphore,SS_SIZE
- LONG ClickWindow
- STRUCT ClickTime,TV_SIZE
- LONG ClickCount
- LONG Path
- LONG ChipData
- LONG RealBackground
- LONG OriginalCopInit
- LONG ScreenPtr
-
- LABEL Sigs
- LONG CLISig
- LONG QuitSig
- LONG ScreenToBackSig
- LONG WBenchToFrontSig
- LABEL EndSigs
-
- LABEL Options
- LONG MBlankOption
- LONG SBlankOption
- LONG FlickerOption
- LONG CmdOption
- LONG AccelOption
- LONG ThreshOption
- LONG CTBOption
- LONG CTFOption
- LONG SunMouseOption
- LONG NorthGateOption
- LONG BeepOption
- LONG QuitOption
-
- BYTE HandlerInstalled
- BYTE Status ;various status bits (defined below)
- LABEL Data_Sizeof
-
- ;Bit definitions for Status
- BITDEF ST,SBlanked,0
- BITDEF ST,SunMouse,1
-
- NumSigs equ (EndSigs-Sigs)/4
-
- STRUCTURE CData,0
- STRUCT ZeroMouse,12
- STRUCT Copper,MaxCopperSize+4*4
- LABEL CData_Sizeof
-
- end
-